package com.xuecheng.base.execption;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @description 全局异常处理器
 * @author Mr.M
 * @date 2022/9/6 11:29
 * @version 1.0
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

   @ResponseBody
   @ExceptionHandler(XueChengPlusException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public RestErrorResponse customException(XueChengPlusException e) {
      log.error("【系统异常】{}",e.getErrMessage(),e);
      return new RestErrorResponse(e.getErrMessage());

   }
   @ResponseBody
   @ExceptionHandler(TeachplanException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public CodeErrorResponse teachPlanException(TeachplanException e) {
      log.error("【系统异常】errCode:{},errMessage{}",e.getErrCode(),e.getErrMessage());
      return new CodeErrorResponse(e.getErrCode(),e.getErrMessage());


   }
   @ResponseBody
   @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public RestErrorResponse handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
      log.error("【数据库唯一约束异常】{}",e.getMessage(),e);

      // 根据错误信息判断具体是哪个唯一约束
      String errorMessage = e.getMessage();
      if (errorMessage.contains("courseid_teacherId_unique")) {
         return new RestErrorResponse("同一课程下教师名称不能重复");
      }

      // 其他唯一约束异常
      return new RestErrorResponse("数据已存在，请勿重复添加");
   }

   @ResponseBody
   @ExceptionHandler(Exception.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public RestErrorResponse exception(Exception e) {

      log.error("【系统异常】{}",e.getMessage(),e);
// 调试：打印异常类型和原因
      log.error("【系统异常】类型: {}, 消息: {}", e.getClass().getName(), e.getMessage(), e);

      // 打印异常链
      Throwable cause = e;
      int depth = 0;
      while (cause != null && depth < 10) {
         log.error("【异常链】深度 {}: {} - {}", depth, cause.getClass().getName(), cause.getMessage());
         cause = cause.getCause();
         depth++;
      }
      // 检查是否是包装的 SQLIntegrityConstraintViolationException
      cause = e;
      while (cause != null) {
         if (cause instanceof SQLIntegrityConstraintViolationException) {
            return handleSQLIntegrityConstraintViolationException((SQLIntegrityConstraintViolationException) cause);
         }
         cause = cause.getCause();
      }

      return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());

   }
}